﻿
using System;
using System.Threading;

namespace HmFramework.Threading
{

	/// <summary>
	/// Use Monitor.TryEnter to acquire a lock. This would not cause the dead lock.
	/// </summary>
	public class DisposableLocker : IDisposable
	{

		private object _syncRoot;
		private Boolean _lockAcquired;
		private Int32 _millisecondsTimeout;

		public DisposableLocker(object syncRoot, Int32 millisecondsTimeout)
		{
			_syncRoot = syncRoot;
			_millisecondsTimeout = millisecondsTimeout;
			_lockAcquired = Monitor.TryEnter(_syncRoot, _millisecondsTimeout);
			LogWhenAcquireLockFailed();
		}

		private void LogWhenAcquireLockFailed()
		{
			if (!_lockAcquired)  //这时候可能要如下处理：（1）记录日志；（2）记录日志并抛出异常；（3）记录日志，然后Block，重现死锁。
			{
				//Console.WriteLine(String.Format(
				//    "Accquire the lock timeout. The limited time is {0} milliseconds.",
				//    _millisecondsTimeout));
			}
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		private void Dispose(Boolean disposing)
		{
			if (disposing)
			{
				if (_lockAcquired)
				{
					Monitor.Exit(_syncRoot);
				}
			}
		}

		~DisposableLocker()
		{
			Dispose(false);
		}
	}
}
